<template>
  <vxe-grid v-bind="gridOptions"
    ref="gridRef"
    class="rk-grid"
    @radioChange="radioChange"
    @currentChange="currentChange">
    <!-- 取消单选 -->
    <template #radio_header>
      <el-button link v-if="radioCacelBtn"
        type="primary"
        size="small"
        :disabled="!radioRow"
        @click="clearRadioRow(true)">取消</el-button>
    </template>
    <!-- 工具栏左侧 -->
    <template #toolbar_left>
      <TitleBar :title="title" v-show="title && showTitle" />
      <div class="toolbar-buttons">
        <slot name="toolbar_left"></slot>
      </div>
    </template>
    <!-- 工具栏右侧 -->
    <template #toolbar_right>
      <div class="toolbar-right">
        <template v-if="isSqlData">
          <AmtUnitSelect
            v-if="amtUnitConfig.enabled"
            class="toolbar-item"
            v-model="queryParams.params.dw"
            @change="amtUnitChange()"
          />
        </template>
        <template v-else>
          <AmtUnitSelect
            v-if="amtUnitConfig.enabled"
            class="toolbar-item"
            v-model="queryParams.dw"
            @change="amtUnitChange()"
          />
        </template>
        
        <slot name="toolbar_right"></slot>
        <slot name="toolbar_right_btn"></slot>
      </div>
    </template>
    <template v-for="slotName in columnsInfo.columnSlots"
      :key="slotName"
      v-slot:[slotName]="params">
      <slot :name="slotName"
        v-bind="params"></slot>
    </template>
  </vxe-grid>
</template>

<script setup>
import TitleBar from './components/TitleBar.vue';
import AmtUnitSelect from './components/AmtUnitSelect.vue'

import XEUtils from 'xe-utils';
import TableUtils, { getTotaledRow, getAverageRow } from '../cfg/table-utils'
import { useAttrs, useSlots, reactive, ref, watch, nextTick, computed } from 'vue';

import { compProps, defaultProps } from '../cfg/table-props';

import { useProxyConfig } from '../hook/useProxyConfig.js';
import { useColumnsConfig } from '../hook/useColumnsConfig.js';

const slots = useSlots();
const attrs = useAttrs();
// 转换attrs的key为驼峰式命名
const parseAttrs = () => {
  const result = {}
  if (attrs) {
    Object.keys(attrs).forEach((key) => {
      result[TableUtils.toCamelCase(key)] = attrs[key]
    })
  }
  return result
}
const shiftAttrs = parseAttrs()

const emits = defineEmits([
  'loaded', 'radioChange', 'currentChange', 'refresh', 'totalRowChange'
]);

const props = defineProps({
  ...compProps,
  // 是否restful风格请求
  restful: { type: [Boolean], default: false },
  // 是否设计状态
  designState: { type: Boolean, default: false },
  // 是否展示金额下拉选项
  amtUnitSelect: { type: [Boolean, Object], default: false },
  // 合计变化第一次是否触发，默认不触发
  firstCalcTotal: { type: Boolean, default: false },
  // 是否显示取消按钮
  radioCacelBtn: { type: Boolean, default: true },
  //
  dataType: { type: String, default: 'REQ' },
});

// 表格的组件实例
const gridRef = ref(null);

// 表格配置信息
const gridOptions = reactive({
  ...shiftAttrs,
  ...defaultProps.baseAttrs,
});

// hooks
const hooksParams = { props, attrs: shiftAttrs, emits, slots, gridRef, gridOptions }
const { initProxyConfig, resetParams, queryParams } = useProxyConfig(hooksParams);
const { columnsInfo, initColumnsConfig } = useColumnsConfig(hooksParams);

const isSqlData = computed(() => {
  return props.dataType === 'SQL'
})

/** 表格配置初始化 */
const initGridConfig = () => {
  initEditConfig();
  initPagerConfig();
  initProxyConfig();
  initColumnsConfig();
  initDefaultConfig();
  initToolbarConfig();
  initTooltipConfig();
  initAmtUnitConfig();
  initFooterMethod();
};

// vxe-table中需要导出的方法名
const vxeEventsName = reactive([
  'remove',
  'insertAt',
  'insertNextAt',
  'reloadRow',
  'revertData',
  'reloadData',
  'commitProxy',
  'removeRadioRow',
  'removeCheckboxRow',
  'getData',
  'getTableData',
  'getEditRecord',
  'getRadioRecord',
  'getUpdateRecords',
  'getRemoveRecords',
  'getCurrentRecord',
  'getInsertRecords',
  'getCheckboxRecords',
  'isEditByRow',
  'isInsertByRow',
  'isTreeExpandByRow',
  'clearAll',
  'clearData',
  'clearEdit',
  'clearCurrentRow',
  'clearCheckboxRow',
  'setEditRow',
  'setRadioRow',
  'setCurrentRow',
  'setEditCell',
  'setTreeExpand',
  'setAllTreeExpand',
  // 'updateFooter',
  'scrollToRow',
  'refreshColumn',
  'hideColumn',
  'showColumn',
]);
const footerData = reactive({
totaledRow:{},
averageRow:{} 
})
// vxe-table中需要导出的方法值
const vxeEventsValue = reactive({});
/** 初始化表格方法 */
const initGridEvents = () => {
  // 导出vxe-table原有的一些方法
  vxeEventsName.forEach((name) => (vxeEventsValue[name] = (...params) => gridRef.value[name](...params)));
};

/** 初始化编辑配置 */
const initEditConfig = () => {
  const { editConfig } = props
  const { keepSource } = shiftAttrs
  let finalConfig = null;
  const defaultConfig = defaultProps.editConfig;
  if (editConfig && XEUtils.isBoolean(editConfig)) {
    finalConfig = { ...defaultConfig };
  } else if (editConfig && XEUtils.isObject(editConfig)) {
    finalConfig = { ...defaultConfig, ...editConfig };
  }
  if (finalConfig && keepSource) {
    finalConfig.showStatus = keepSource
  }
  if (!finalConfig) return;
  gridOptions['editConfig'] = finalConfig;
}

// 监听分页配置
watch(
  () => props.pagerConfig,
  (newValue, oldValue) => {
    initPagerConfig()
  },
  { deep: true, immediate: false },
);
/** 初始化表格分页配置 */
const initPagerConfig = () => {
  const { pagerConfig } = props;
  let finalConfig = null;
  const defaultConfig = defaultProps.pagerConfig;
  if (XEUtils.isBoolean(pagerConfig)) {
    finalConfig = { ...defaultConfig, enabled: pagerConfig };
  } else if (pagerConfig && XEUtils.isObject(pagerConfig)) {
    finalConfig = { ...defaultConfig, ...pagerConfig };
  }
  if (!finalConfig) return;
  gridOptions['pagerConfig'] = finalConfig;
};

// 监听工具栏配置
watch(
  () => props.toolbarConfig,
  (newValue, oldValue) => {
    initToolbarConfig()
  },
  { deep: true, immediate: false },
);
/**
 * 初始化工具栏
 */
const initToolbarConfig = () => {
  const { toolbarConfig, title } = props;
  
  let finalConfig = null;
  const defaultConfig = defaultProps.toolbarConfig;
  // 重写刷新方法
  defaultConfig.refresh = {
    queryMethod: () => {
      return new Promise((reslove, reject) => {
        if (props.dataUrl) {
          if (props.autoRefresh) searchEvent();
          emits('refresh')
          reslove(true);
        } else {
          emits('refresh')
          reslove(true);
        }
      });
    }
  }
  // 类型判断
  if (XEUtils.isBoolean(toolbarConfig)) {
    // 布尔类型
    if (toolbarConfig) {
      finalConfig = { ...defaultConfig };
    } else {
      finalConfig = null
    }
  } else if (XEUtils.isObject(toolbarConfig)) {
    // 对象类型
    if (XEUtils.isEmpty(toolbarConfig)) {
      finalConfig = { ...defaultConfig };
    } else {
      finalConfig = { ...defaultConfig, ...toolbarConfig };
    }
  } else {
    // 其他类型
    console.warn('toolbarConfig配置格式不正确，请确认！')
  }

  if (!finalConfig) return;
  gridOptions['toolbarConfig'] = finalConfig;

  nextTick(() => {
    setTimeout(() => {
      // 处理工具栏的样式
      const toolbarRightDom = document.querySelector('.toolbar-right')
      if (toolbarRightDom) {
        toolbarRightDom.children.forEach(dom => {
          dom.classList.add('toolbar-item')
        })
      }
    }, 300)
  })
};
/**
 * 初始化ooltip 配置项
 */
const initTooltipConfig = () => {
  const defaultConfig = defaultProps['tooltipConfig']
  // 重写默认的提示内容
  const contentMethod = (params) => {
    const { column, row, cell } = params
    // 操作列去除tooltip提示
    if (column && row && ['operation'].includes(column.field)) { return '' }
    // 返回横线，去除tooltip提示
    const textContent = cell.textContent
    // 处理自定义字段不显示tooltip
    if (columnsInfo.noTooltipColumns && columnsInfo.noTooltipColumns.length) {
      if (column && row && columnsInfo.noTooltipColumns.includes(column.field)) { return '' }
    }
    if (textContent === '-' || textContent === '－') { return '' }
    return null
  }
  defaultConfig.contentMethod = contentMethod
  gridOptions['tooltipConfig'] = defaultConfig;
}

const someStore = reactive({
  notFirstCalcTotalRow: !props.firstCalcTotal,
})
/**
 * 初始化表尾方法配置
 */
const initFooterMethod = () => {
  const { totaled, average, footerMethod } = props
  let customFooterMethod = null
  let dynamicFooterMethod = footerMethod || null
  const existFooter = (totaled || average)
  // 存在合计行
  if (existFooter) {
    customFooterMethod = (params) => {
      if (!params) return []
      // 获取合计行
      const totaledRow = getTotaledRow(params, {
        fields: columnsInfo.totaledFields,
        formats: columnsInfo.totaledFormats
      })
      // 获取平均数行
      const averageRow = getAverageRow(params, {
        fields: columnsInfo.averageFields,
        formats: columnsInfo.averageFormats
      })
      footerData.totaledRow = totaledRow
      footerData.averageRow = averageRow
      // 返回表尾数据
      let finalFooter = []
      // 获取平均数行
      if (props.average && columnsInfo.averageFields && columnsInfo.averageFields.length) finalFooter.push(averageRow)
      if (props.totaled && columnsInfo.totaledFields && columnsInfo.totaledFields.length) {
        finalFooter.push(totaledRow.totalRow)
        if (!someStore.notFirstCalcTotalRow) {
          emits('totalRowChange', totaledRow)
        }
        someStore.notFirstCalcTotalRow = false
      }
      return finalFooter
    }
  }
  if ((customFooterMethod || dynamicFooterMethod)) {
    gridOptions['footerMethod'] = (params) => {
      let finalResult = []
      if (customFooterMethod) {
        let custonResult = customFooterMethod(params)
        finalResult = [ ...finalResult, ...custonResult ]
      }
      if (dynamicFooterMethod) {
        let dynamicResult = dynamicFooterMethod(params)
        finalResult = [ ...finalResult, ...dynamicResult ]
      }
      return finalResult
    };
  } else {
    gridOptions['footerMethod'] = (params) => {
      return []
    }
  }
}

/** 初始化一些默认配置 */
const configNames = ['rowConfig', 'sortConfig', 'radioConfig', 'columnConfig', 'checkboxConfig',];
const initDefaultConfig = () => {
  configNames.forEach((name) => {
    gridOptions[name] = { ...defaultProps[name], ...shiftAttrs[name] }
  });
  if (props.keyField) gridOptions.rowConfig['keyField'] = props.keyField
};

/** 关于单位下拉选项的配置 */
const amtUnitConfig = reactive({
  enabled: false,
  autoLoad: true
})
const amtUnitChange = () => {
  if (!amtUnitConfig.autoLoad) return
  if (props.designState) return
  searchEvent()
}

// 监听单位筛选配置
watch(
  () => props.amtUnitSelect,
  (newValue, oldValue) => {
    initAmtUnitConfig()
  },
  { deep: true, immediate: false },
);
const initAmtUnitConfig = () => {
  const { amtUnitSelect } = props
  if (amtUnitSelect && XEUtils.isBoolean(amtUnitSelect)) {
    amtUnitConfig.enabled = amtUnitSelect
  } else if (amtUnitSelect && XEUtils.isObject(amtUnitSelect)) {
    amtUnitConfig.enabled = amtUnitSelect.enabled
    amtUnitConfig.autoLoad = amtUnitSelect.autoLoad
  } else {
    amtUnitConfig.enabled = false
  }
  if (amtUnitConfig.enabled) {
    // SQL数据
    if (isSqlData.value) {
      if (queryParams.value.params) {
        queryParams.value.params['dw'] = 10000
      } else {
        queryParams.value.params = { dw: 10000 }
      }
    } else {
      queryParams.value['dw'] = 10000
    }
  } else {
      if (queryParams.value.params) {
        delete queryParams.value.params['dw']
      } else {
        delete queryParams.value.dw
      }
  }
}

// ------ 表格单选操作
// 单选选中的行
const radioRow = ref(null)
/**
 * 单选变化触发
 * @param {Object} values 参数
 */
const radioChange = (values) => {
  radioRow.value = values.row
  emits('radioChange', values)
}
const currentChange = (values) => {
  emits('currentChange', values)
}
/**
 * 情况单选选中
 * @param {Boolean} isEmit 是否触发向上事件
 */
const clearRadioRow = (isEmit = false) => {
  radioRow.value = null;
  gridRef.value.clearRadioRow();
  gridRef.value.clearCurrentRow();
  if (!isEmit) return
  emits('radioChange', null)
}

/**
 * 重置查询
 *
 * @param {Object} params 参数
 */
const resetEvent = (params) => {
  const finalParams = resetParams(params);
  radioRow.value = null;
  gridRef.value.commitProxy(props.refreshType);
  return finalParams;
}
/**
 * 查询方法
 *
 * @param {String} type 查询类型 reload|query
 * @param {Object} params 参数
 */
const searchEvent = (type = 'reload', params = {}) => {
  const tableRef = gridRef.value;
  radioRow.value = null;
  // const finalParams = mergeParams(params);
  // console.log('searchEvent', finalParams)
  setTimeout(() => {
    if (tableRef) tableRef.commitProxy(type || props.refreshType)
  }, 100)
  // return finalParams;
}
const getFooterData = ()=>{
  return footerData 
}


// 运行初始化方法
initGridConfig();
// 运行初始化事件
initGridEvents();

// console.log('gridOptions', {attrs, props, gridOptions, shiftAttrs});

defineExpose({
  ...vxeEventsValue,
  resetEvent,
  searchEvent,
  clearRadioRow,
  getFooterData
});
</script>

<style lang="scss">
@import '../style/vf-table.scss';
</style>
